/*
 *  File : VariableLengthStringKeyGenerator.java
 *  Created By : madhurt
 *  Created On : Oct 7, 2010
 *  Yahoo! 2010
 */
package com.gebogebo;

import com.gebogebo.key.MultiValueAlphaNumericKey;
import com.gebogebo.key.ValueOverflowException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author madhurt
 */
public class VariableLengthStringKeyGenerator {

    private final int MAX_NO_OF_CHARS_IN_KEY;
    private long noOfKeysGenerated = 0;
    private int currNoOfCharsInKey = 1;
    private MultiValueAlphaNumericKey multiValueKey;
    private static final Logger logger = Logger.getLogger(VariableLengthStringKeyGenerator.class.getName());

    public VariableLengthStringKeyGenerator(int noOfCharsPerKey) {
        this.MAX_NO_OF_CHARS_IN_KEY = noOfCharsPerKey;
        currNoOfCharsInKey = 1;
        multiValueKey = new MultiValueAlphaNumericKey(currNoOfCharsInKey);
    }

    public synchronized String generateKey() {
        try {
            if (noOfKeysGenerated >= maxNoOfPossibleKeysWithChars(currNoOfCharsInKey)) {
                currNoOfCharsInKey++;
                multiValueKey = new MultiValueAlphaNumericKey(currNoOfCharsInKey);
            }

            if (currNoOfCharsInKey > MAX_NO_OF_CHARS_IN_KEY) {
                throw new ValueOverflowException("c : " + currNoOfCharsInKey + ", max : " + MAX_NO_OF_CHARS_IN_KEY);
            }

            Character[] nextValue = multiValueKey.nextValue();

            //System.out.println("Next Val : " + Arrays.toString(nextValue));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < currNoOfCharsInKey; i++) {
                sb.append(nextValue[i]);
            }
            noOfKeysGenerated++;
            return sb.toString();

        } catch (ValueOverflowException ex) {
            logger.log(Level.SEVERE, "ValueOverflowException", ex);
            throw new RuntimeException(ex);
        }
    }

    public static void main(String[] args) {

        VariableLengthStringKeyGenerator kg = new VariableLengthStringKeyGenerator(2);

        long cnt = 0;
        for (int i = 0; i < 64; i++) {
            cnt++;
            System.out.println(kg.generateKey());
        }

        for (int i = 0; i < 64 * 64; i++) {
            kg.generateKey();
            cnt++;
            System.out.println(kg.generateKey());
        }

        /*for(int i =0 ; i < 64*64*64; i++) {
        kg.generateKey();
        cnt++;
        System.out.println(kg.generateKey());
        }

        for(int i =0 ; i < 64*64*64*64; i++) {
        kg.generateKey();
        cnt++;
        System.out.println(kg.generateKey());
        }

        for(int i =0 ; i < 64*64*64*64*64; i++) {
        kg.generateKey();
        cnt++;
        System.out.println(kg.generateKey());
        }*/

        System.out.println("Cnt : " + cnt);

        String key = kg.generateKey();
        System.out.println("Key : " + key);
    }

    private long maxNoOfPossibleKeysWithChars(int currNoOfCharsInKey) {
        int keyVariations = 64;
        long totalVariations = 0;
        for (int i = 1; i <= currNoOfCharsInKey; i++) {
            totalVariations += Math.pow(keyVariations, i);
        }

        return totalVariations;
    }
}
